#include "StdAfx.h"

#include "GameSession.h"
#include "GameApp.h"
#include "CoreEvents.h"

GameSession::GameSession(void)
{
}

GameSession::~GameSession(void)
{
}

void GameSession::OnEvent(Event* evt)
{
	inherited::OnEvent(evt);

	BEGIN_EVENT_HANDLER(evt);

	ON_EVENT(FrameUpdatedEvent)
	{
		m_sessionTime += evt->DT;
	}

	END_EVENT_HANDLER;

	m_TaskChannel->Broadcast(evt);
}

void GameSession::StartSession()
{
	m_MainChannel = g_EventService->CreateChannel();
	m_TaskChannel = g_EventService->CreateChannel();
	
	g_RenderService->CreateDefaultRender();
	
	m_SceneManager	= g_RenderService->GetDefSceneManager();
	m_Camera		= g_RenderService->GetDefCamera();
	
	m_sessionTime	= 0.0f;

	g_InputService->StartInputTask();
	Start();
}

void GameSession::StopSession()
{
	g_InputService->StopInputTask();

	SessionStopEvent evt;
	m_TaskChannel->Broadcast(&evt);
	m_MainChannel->Broadcast(&evt);

	Stop();

	m_Camera = NULL;
	m_SceneManager = NULL;
}

void GameSession::SetCamera(Camera* camera)
{
	if (m_Camera == camera)
		return;

	m_Camera = camera;

	// AdjustAspectRatio
}

GameSession* GameSession::CreateByName(const char* name, const char* arg)
{
	GameSession* session = NULL;
	
	for (Registry* r = Registry::GetHead(); r; r = r->Next)
	{
		if (strcmp(r->Name, name) == 0)
		{
			session = r->Constructor(arg);
			break;
		}
	}

	if (session == NULL)
		return NULL;

	session->m_Name		= name;
	session->m_Argument	= arg;

	return session;
}

///////////////////////////////////

IMPLEMENT_EVENT(SessionStopEvent);

///////////////////////////////////

GameSession::Registry::Registry(ConstructorFn constructor, const char* name)
: Constructor(constructor), Name(name)
{
	Next = Add(this);
}

GameSession::Registry*& GameSession::Registry::GetHead()
{
	static Registry* head = NULL;
	return head;
}

GameSession::Registry* GameSession::Registry::Add(Registry* r)
{
	Registry*& head = GetHead();
	Registry* next = head;
	head = r;

	return next;
}

std::string GameSession::Registry::GetSessionList()
{
	std::string ret;

	for (Registry* r = GetHead(); r; r = r->Next)
	{
		ret += r->Name;
		ret += " ";
	}

	return ret;
}